/*
 * expression.h
 *
 *  Created on: Jan 9, 2012
 *      Author: liuhaifeng
 */

#ifndef _EXPRESSION_H_
#define _EXPRESSION_H_

#include <dataset.h>

#define EXP_MAX_IDENTITY   32
#define EXP_MAX_OPERATOR   8
#define EXP_MAX_CONSTANT   512

#define EXP_MAX_STRING     EXP_MAX_CONSTANT
#define EXP_MAX_TOKEN      EXP_MAX_CONSTANT

#define EXP_TOKEN_OPR      1
#define EXP_TOKEN_IDENT    2
#define EXP_TOKEN_CONST    3
#define EXP_TOKEN_COMMA    4

#define EXP_CONSTANT       1
#define EXP_IDENTITY       2
#define EXP_FUNCTION       3
#define EXP_UNARY          4
#define EXP_BIGRAM         5

#define EXP_OPR_UNKNOWN    0
#define EXP_OPR_YES        1
#define EXP_OPR_NOT        2
#define EXP_OPR_AND        3
#define EXP_OPR_OR         4
#define EXP_OPR_EQUALS     100
#define EXP_OPR_START_WITH 101
#define EXP_OPR_CONTAINS   102
#define EXP_OPR_END_WITH   103
#define EXP_OPR_PARENTHESIS_OPEN  201
#define EXP_OPR_PARENTHESIS_CLOSE 202

#define EXP_OPR_TERM       400

#define IS_LETTER(x)  (((x) >= 'a' && (x) <= 'z') || ((x) >= 'A' && (x) <= 'Z'))
#define IS_NUMBER(x)  ((x) >= '0' && (x) <= '9')

typedef struct st_exp_token {
	int type;
	char content[EXP_MAX_TOKEN];
} ExpToken;

typedef struct st_expression Expression;

typedef struct st_exp_function {
	char name[EXP_MAX_IDENTITY];
	list *parameters;
} ExpFunction;

typedef int ExpOperator;

typedef struct st_exp_unary {
	int opr;
	Expression *a;
} ExpUnary;

typedef struct st_exp_bigram {
	int opr;
	Expression *a, *b;
} ExpBigram;

struct st_expression {
	int type;
	union {
		char constant[EXP_MAX_CONSTANT];
		char ident[EXP_MAX_IDENTITY];
		ExpFunction func;
		ExpUnary unary;
		ExpBigram bigram;
	} exp;
};

typedef int(*IdentEval)(char *, const char *, void *);
typedef int(*FuncEval)(char *, ExpFunction *, IdentEval, void *);

extern const char * exp_parse(Expression **exp, const char *src,
		const char stop);

extern int exp_eval(BOOL *ret, Expression *exp, IdentEval ident_eval,
		FuncEval func_eval, void *);

extern void exp_destroy(Expression *exp);

#endif /* _EXPRESSION_H_ */
